package com.jxpanda.spring.module.wechat.controller;

import com.jxpanda.spring.module.wechat.component.message.WechatCallbackProcessor;
import com.jxpanda.spring.module.wechat.component.message.WechatCorpMessageService;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

/**
 * 微信企业号控制器接口。
 * 该接口定义了处理微信企业号回调消息的规范。
 *
 * @author Panda
 */
public interface IWechatCorpController {

    /**
     * 获取微信企业号消息服务。
     * 该方法用于获取与微信企业号交互的消息服务实例。
     *
     * @return 微信企业号消息服务实例。
     */
    WechatCorpMessageService wechatCorpService();

    /**
     * 验证微信回调URL的合法性。
     * 当微信服务器向应用的回调URL发送请求时，会携带签名信息等，通过该方法进行验证。
     *
     * @param appName      应用名称，用于标识不同的微信应用。
     * @param msgSignature 消息签名，用于验证请求的合法性。
     * @param timestamp    时间戳。
     * @param nonce        随机数。
     * @param echoStr      微信服务器发送的回显字符串，用于验证请求的真实性。
     * @return 验证通过后返回的回显字符串。
     */
    @GetMapping(value = "/callback/{appName}", produces = MediaType.TEXT_PLAIN_VALUE)
    default Mono<String> verifyUrl(@PathVariable("appName") String appName,
                                   @RequestParam("msg_signature") String msgSignature,
                                   @RequestParam("timestamp") String timestamp,
                                   @RequestParam("nonce") String nonce,
                                   @RequestParam("echostr") String echoStr) {
        WechatCallbackProcessor wechatCallbackProcessor = WechatCallbackProcessor.builder()
                .appName(appName)
                .msgSignature(msgSignature)
                .timestamp(timestamp)
                .nonce(nonce)
                .build();
        return wechatCorpService().callbackUrlVerify(echoStr, wechatCallbackProcessor);
    }

    /**
     * 处理微信回调消息。
     * 当应用接收到来自微信的回调消息时，通过该方法进行处理。
     *
     * @param appName      应用名称，用于标识不同的微信应用。
     * @param msgSignature 消息签名，用于验证请求的合法性。
     * @param timestamp    时间戳。
     * @param nonce        随机数。
     * @param requestBody  微信回调的消息内容。
     * @return 处理结果，通常为XML格式的消息响应。
     */
    @PostMapping(value = "/callback/{appName}", produces = MediaType.APPLICATION_XML_VALUE)
    default Mono<String> callback(@PathVariable("appName") String appName,
                                  @RequestParam("msg_signature") String msgSignature,
                                  @RequestParam("timestamp") String timestamp,
                                  @RequestParam("nonce") String nonce,
                                  @RequestBody String requestBody) {
        WechatCallbackProcessor wechatCallbackProcessor = WechatCallbackProcessor.builder()
                .appName(appName)
                .msgSignature(msgSignature)
                .timestamp(timestamp)
                .nonce(nonce)
                .build();
        return wechatCorpService().callbackMessageProcess(requestBody, wechatCallbackProcessor);
    }

}

